package cn.edu.suda.ada.database.objects;

import cn.edu.suda.ada.common.utils.PatternUtils;

import java.util.regex.Matcher;

/**
 * 数据列结构类
 *
 * @param <T> 默认值类型，即数据列的类型
 * @author JiangJun
 */
public class Column<T> implements Cloneable {
    /**
     * 列名
     */
    private String name;
    /**
     * 数据类型
     */
    private Type type;
    /**
     * 长度
     */
    private Integer length = null;
    /**
     * 是否允许空值
     */
    private Boolean empty = true;
    /**
     * 默认值
     */
    private T defaultVal;
    /**
     * 其他扩展信息
     */
    private String extra;
    /**
     * 注释
     */
    private String comment = "";

    public Column(String name, String type, Integer length) {
        super();
        this.name = name;
        this.type = Type.getType(type);
        this.length = length;
    }

    public Column(String name, String type) {
        super();
        this.name = name;
        Matcher matcher = PatternUtils.getDefaultMatcher(type, "(\\w+)\\((\\d+)\\)");
        if (matcher.find()) {
            this.type = Type.getType(matcher.group(1));
            String length = matcher.group(2);
            if (null != length) {
                this.length = Integer.parseInt(length);
            }
        }
    }

    public Column(String name, Type type, Integer length) {
        super();
        this.name = name;
        this.type = type;
        this.length = length;
    }

    /**
     * 获得数据列实例
     *
     * @param name 列名
     * @param type 类型
     * @param def  默认值
     * @return 数据列实例
     */
    public static Column<?> getColumn(String name, String type, String def) {
        Matcher matcher = PatternUtils.getDefaultMatcher(type, "(\\w+)\\((\\d+)\\)");
        if (matcher.find()) {
            Type columnType = Type.getType(matcher.group(1));
            String length = matcher.group(2);
            int columnLength = 0;
            if (null != length) {
                columnLength = Integer.parseInt(length);
            }
            switch (columnType) {
                case INT:
                    Column<Integer> integerColumn = new Column<Integer>(name, type, columnLength);
                    if (null != def) {
                        integerColumn.setDefaultVal(Integer.parseInt(def));
                    }
                    return integerColumn;
                case STRING:
                case DATE:
                default:
                    Column<String> stringColumn = new Column<String>(name, type, columnLength);
                    if (null != def) {
                        stringColumn.setDefaultVal(def);
                    }
                    return stringColumn;
            }
        }
        return null;
    }

    /**
     * 数据列类型
     */
    public enum Type {
        STRING("VARCHAR"), INT("INT"), DATE("DATETIME");
        private String key;

        Type(String key) {
            this.key = key;
        }

        @Override
        public String toString() {
            return key;
        }

        /**
         * 根据数据库字段类型获得相应数据列类型
         *
         * @param type 当前数据库字段类型
         * @return 数据列类型
         */
        public static Type getType(String type) {
            switch (type.toUpperCase()) {
                case "DATETIME":
                    return DATE;
                case "INT":
                    return INT;
                default:
                    return STRING;
            }
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Type getType() {
        return type;
    }

    public void setType(Type type) {
        this.type = type;
    }

    public Integer getLength() {
        return length;
    }

    public void setLength(Integer length) {
        this.length = length;
    }

    public Boolean isEmpty() {
        return empty;
    }

    public void setEmpty(Boolean empty) {
        this.empty = empty;
    }

    public T getDefaultVal() {
        return defaultVal;
    }

    public void setDefaultVal(T defaultVal) {
        this.defaultVal = defaultVal;
    }

    public String getExtra() {
        return extra;
    }

    public void setExtra(String extra) {
        this.extra = extra;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    @Override
    public int hashCode() {
        if (null == name) {
            return super.hashCode();
        }
        return name.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Column)) {
            return false;
        }
        Column<?> col = (Column<?>) obj;
        return !(null == col.getName() || null == name) && col.getName().equals(name);
    }

    @Override
    public String toString() {
        return String.format("Column : {name = %s , type = %s , length = %d , empty = %s, defaultVal = %s , extra = %s , comment = %s}",
                name, type, length, empty, defaultVal, extra, comment);
    }

    /**
     * 拷贝当前列
     */
    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
}
